package com.ruoyi.common.utils.oss;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.List;

/**
 * @Author: yan
 * @Description:
 * @Date: create in 2021/12/14 11:37
 */
public class OSSClientUtil {
    /**
     * 请求地址
     */
    private String endpoint = "http://oss-cn-beijing.aliyuncs.com";
    /**
     * key
     */
    private String accessKeyId = "LTAI5tFksikje4LPacMEtXbb";
    /**
     * 密钥
     */
    private String accessKeySecret = "OeB0vkZeDMbpZAKL2KMuu4bgiKNtEX";
    /**
     * 空间
     */
    private String bucketName = "aitax";

    /**
     * 文件存储目录
     */
    private String fileDir = "ai/";
    /**
     * 上传最大限制
     */
    private int fileMaxSize = 10;


    public OSS getOssClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * 销毁
     */
    public void destory(OSS ossClient) {
        ossClient.shutdown();
    }

    /**
     * 上传图片
     *
     * @param url
     */
    public void uploadImg2Oss(String url, OSS ossClient) throws FileNotFoundException {
        File fileOnServer = new File(url);
        InputStream fin;
        fin = new FileInputStream(fileOnServer);
        String[] split = url.split("/");
        this.uploadFile2OSS(fin, split[split.length - 1], ossClient);
    }


    public String uploadImg2Oss(MultipartFile file, OSS ossClient) throws IOException {
        String code = getCode(file.getInputStream());
        System.out.println(code);
        if (file.getSize() > 1024 * 1024 * fileMaxSize) {
            throw new IOException("上传图片大小不能超过" + fileMaxSize + "M！");
        }
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        Date now = new Date();
        String nowStr = DateUtils.formatDateTime(now) + IdUtils.simpleUUID();
        String name = nowStr.replaceAll("-", "/").replace(" ", "/MC") + substring;
        InputStream inputStream = file.getInputStream();
        this.uploadFile2OSS(inputStream, name, ossClient);
        return name;
    }

    /**
     * 获得图片路径
     *
     * @param fileUrl
     * @return
     */
    public String getImgUrl(String fileUrl, OSS ossClient) {
        if (!StringUtils.isEmpty(fileUrl)) {
            String[] split = fileUrl.split("/");
            return this.getUrl(this.fileDir + split[split.length - 1], ossClient);
        }
        return null;
    }

    /**
     * 上传到OSS服务器  如果同名文件会覆盖服务器上的
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2OSS(InputStream instream, String fileName, OSS ossClient) {
        String ret = "";
        try {
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            //上传文件
            PutObjectResult putResult = ossClient.putObject(bucketName, fileDir + fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getContentType(String FilenameExtension) {
        if (".bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(FilenameExtension) ||
                ".jpg".equalsIgnoreCase(FilenameExtension) ||
                ".png".equalsIgnoreCase(FilenameExtension)) {
            return "image/jpeg";
        }
        if (".html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if (".pptx".equalsIgnoreCase(FilenameExtension) ||
                ".ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".docx".equalsIgnoreCase(FilenameExtension) ||
                ".doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        return "application/octet-stream";
    }

    /**
     * 获得url链接
     *
     * @param key
     * @return
     */
    public String getUrl(String key, OSS ossClient) {
        // 设置URL过期时间为10年  3600l* 1000*24*365*10
        Date nowDate = new Date();
        long time = nowDate.getTime();
        Date expiration = new Date(time + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        if (url != null) {
            return url.toString();
        }
        return null;
    }


    /**
     * 删除某个Object
     * http://127.0.0.1:8080/a/oss/del?url= sys/2019-11-16MC11:34:52.png
     *
     * @param bucketUrl
     * @return
     */
    public boolean deleteObject(String bucketUrl, OSS ossClient) {
        try {
            boolean b = ossClient.doesObjectExist(bucketName, bucketUrl);
            System.out.println("查询文件是否存在：" + b + "=================================");
            if (!b) {
                System.out.println("Error: OSS file not find,file:{} ===============");
                return false;
            }
            // 删除Object.
            ossClient.deleteObject(bucketName, bucketUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            this.destory(ossClient);
        }
        return true;
    }

    /**
     * 删除多个Object
     *
     * @param bucketUrls
     * @return
     */
    public boolean deleteObjects(List<String> bucketUrls, OSS ossClient) {
        try {
            // 删除Object.
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(bucketUrls));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            this.destory(ossClient);
        }
        return true;
    }

    private static String getCode(InputStream inputStream) {
        String code = "gb2312";
        byte[] head = new byte[3];
        try {
            inputStream.read(head);
            inputStream.close();
            System.out.println(head[0]);
            if (head[0] == -1 && head[1] == -2) {
                code = "UTF-16";
            } else if (head[0] == -2 && head[1] == -1) {
                code = "Unicode";
            } else if (head[0] == -17 && head[1] == -69 && head[2] == -65) {
                code = "UTF-8";
            }
        } catch (IOException e) {
            return code;
        }
        return code;
    }
}
